package cc.rboot.inject.helper;

import cc.rboot.inject.core.IMapperInjector;
import cc.rboot.inject.core.InjectConstant;
import cc.rboot.inject.template.*;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class InjectMapperHelper {

    public static <R> R execute(Object that, Class<? extends IMapperInjector> injectMapperClass, Object... params) throws Exception {
        IMapperInjector controller = injectMapperClass.newInstance();

        if (that instanceof IMapperInjector) {
            controller.setService(((IMapperInjector) that).getService());
        } else {
            controller.setService(InjectServiceHelper.injectService(that.getClass()));
        }

        for (Class<? extends Annotation> supportMappingClass : InjectConstant.SUPPORT_MAPPING_CLASSES) {
            for (Method method : injectMapperClass.getMethods()) {
                if (method.isAnnotationPresent(supportMappingClass)) {
                    return (R) method.invoke(controller, params);
                }
            }
        }
        throw new Exception("找不到相应的方法，请开发确认");
    }

    public static <T> T iGet(Object that, Serializable id) throws Exception {
        return InjectMapperHelper.execute(that, InjectGet.class, id);
    }

    public static <T> T iDelete(Object that, Serializable id) throws Exception {
        return InjectMapperHelper.execute(that, InjectDelete.class, id);
    }

    public static <T> T iPost(Object that, T objects) throws Exception {
        return InjectMapperHelper.execute(that, InjectPost.class, objects);
    }


    public static <T> T iPut(Object that, Serializable id, T entity) throws Exception {
        return InjectMapperHelper.execute(that, InjectPut.class, id, entity);
    }

    public static <T> T iPatch(Object that, Serializable id, T entity) throws Exception {
        return InjectMapperHelper.execute(that, InjectPatch.class, id, entity);
    }

    public static <T> IPage<T> iQuery(Object that, Page<T> page, T entity) throws Exception {
        return InjectMapperHelper.execute(that, InjectQuery.class, page, entity);
    }

    public static <T> IPage<T> iQueryAll(Object that, Page<T> page) throws Exception {
        return InjectMapperHelper.execute(that, InjectQueryAll.class, page);
    }

    public static <T> void fillId(T entity, Serializable id) throws Exception {
        // 需要拿到他的ID字段 并赋值
        Class<?> clazz = entity.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(TableId.class)) {
                field.setAccessible(true);

                Class<?> fieldType = field.getType();
                field.set(entity, Convert.convert(fieldType, id));
                break;
            }
        }
    }

}